package com.bdy.lm.taximanager.ui;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.bdy.lm.taximanager.R;
import com.bdy.lm.taximanager.app.MyApp;
import com.bdy.lm.taximanager.http.HttpJson;
import com.bdy.lm.taximanager.model.CarMeasure;
import com.bdy.lm.taximanager.model.DriverInfo;
import com.bdy.lm.taximanager.model.LocationTrack;
import com.bdy.lm.taximanager.model.SerialPortData;
import com.bdy.lm.taximanager.model.StandardRoute;
import com.bdy.lm.taximanager.port.TaxiMeterDataAnalysis;
import com.bdy.lm.taximanager.thread.GetAddress;
import com.bdy.lm.taximanager.util.TimeUtils;
import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class VerifyAdjustActivity extends AppCompatActivity implements GetAddress.Finish, TaxiMeterDataAnalysis.PassQueryMeterData {

    private SharedPreferences sp = this.getSharedPreferences(DriverInfo.getDriverInfo().getICID(), Context.MODE_PRIVATE);
    private StandardRoute sRoute;
    private Context context = this;
    private GetAddress getAddress;
    private Handler handler;
    private TextView textViewA, textViewB, runToBegin, beginAddress;
    private RadioButton selectA, selectB;
    private RadioGroup address;
    private Button select, openBaiduMap;
    private String selectAddr = "", end = "";
    private String aOrb;
    private CarMeasure carMeasure = new CarMeasure();
    private double startMeterPoint, endMeterPoint, ScarMeasure = 0;//计价器开始里程点，结束时里程点，相减测量结果，单位：千米
    private HttpJson httpJson = new HttpJson();
    private ProgressDialog progressDialog;
    private String Aaddress, Baddress;
    private int times = 0;
    private DecimalFormat format = new DecimalFormat("#.000000");
    private boolean beginRecordTrack = true;
    private List<LocationTrack> locationTracks = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_verify_adjust);

        runToBegin = (TextView) findViewById(R.id.run_to_begin);
        //textViewA = (TextView) findViewById(R.id.Aaddress);
        //textViewB = (TextView) findViewById(R.id.Baddress);
        //selectA = (RadioButton) findViewById(R.id.selectA);
        //selectB = (RadioButton) findViewById(R.id.selectB);
        //address = (RadioGroup) findViewById(R.id.address);
        //select = (Button) findViewById(R.id.select);
        //beginAddress = (TextView) findViewById(R.id.begin_address);
        openBaiduMap = (Button) findViewById(R.id.openBaiduMap);

        //设置串口事件回调
        TaxiMeterDataAnalysis.newInstance().setPassQueryMeterDataCallBack(this);

        //address.setOnCheckedChangeListener(checkedListener);
        //select.setOnClickListener(buttonListener);
        progressDialog = new ProgressDialog(this, R.style.AppTheme_Dark_Dialo);
        openBaiduMap.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                try {
                    PackageManager packageManager = getApplicationContext().getPackageManager();
                    Intent intent = packageManager.getLaunchIntentForPackage("com.baidu.BaiduMap");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(intent);
                } catch (NullPointerException e) {
                    Toast t = Toast.makeText(getApplicationContext(), "还没有安装百度地图！！！", Toast.LENGTH_LONG);
                    t.setGravity(Gravity.CENTER, 0, 0);
                    t.show();
                }
            }
        });

        if (sp.contains("StandardRouteNum")){
            int num = sp.getInt("StandardRouteNum", 0);
            String sR = sp.getString(Integer.toString(num), null);
            sRoute = new Gson().fromJson(sR, StandardRoute.class);
            //应该在校准成功后在提交删除
            //sp.edit().clear().commit();
        } else {
            exitActivity("不需要进行检定校准！");
            return;
        }

        //使用百度地图API经纬度
        //getAddress = new GetAddress(sRoute, this);
        //getAddress.start();

        //使用Geocoder解析经纬度，并开始校准
        selectNearestPoint.start();

        waitProgress("正在加载校准地点，请稍后...");

        handler = new Handler() {
            public void handleMessage(Message msg) {
                if (msg.what == 101) {//显示校准起点地址，关闭进度圈，开始检测距离校准起点地址的距离
                    //textViewA.setText(Aaddress);
                    //textViewB.setText(Baddress);
                    runToBegin.setText(selectAddr);
                    checkIsReachStartPoint.start();
                    progressDialog.dismiss();
                } else if (msg.what == 102) {//显示校准终点地址，百度地图按钮可见，开始检测距离校准终点地址的距离
                    runToBegin.setText(end);
                    openBaiduMap.setVisibility(View.VISIBLE);
                    checkIsReachEndPoint.start();
                    Toast.makeText(getApplicationContext(), "已到达校准起点附近，开始进行校准！", Toast.LENGTH_LONG).show();
                    //alert("已到达校准起点附近，开始进行校准！");
                } else if (msg.what == 103) {//启动校准信息处理线程，设置百度地图按钮不可见，显示上传数据进度条
                    finishVerify.start();
                    openBaiduMap.setVisibility(View.INVISIBLE);
                    waitProgress("校准完成，正在上传数据，请稍后...");
                    runToBegin.setText("已到达校准终点附近，正在上传数据...");
                    //alert("已到达校准终点附近，校准结束！");
                    Toast.makeText(getApplicationContext(), "已到达校准终点附近，校准结束！", Toast.LENGTH_LONG).show();
                } else if(msg.what == 104) {
                    progressDialog.dismiss();
                    runToBegin.setText("上传成功，校准完成！！");
                    //alert("上传成功！！");
                } else if(msg.what == 105) {
                    alert("上传失败，请检查网络！！");
                    //Toast.makeText(getApplicationContext(), "上传失败，请检查网络！！", Toast.LENGTH_LONG).show();
                }
            }
        };
    }

    /**
     * 使用百度地图获取经纬度的地址, 暂时不用
     * @param Aaddress
     * @param Baddress
     */
    @Override
    public void setResult(String Aaddress, String Baddress) {
        this.Aaddress = Aaddress;
        this.Baddress = Baddress;
        handler.sendEmptyMessage(101);
    }

    @Override
    public void passQueryMeterData(SerialPortData.QueryMeterPointData queryMeterPointData) {
        if(times == 0) {
            startMeterPoint = queryMeterPointData.getMeterPoint();
            times++;
            System.out.println("startMeterPoint = " + startMeterPoint + "times = " + times);
        } else if(times == 1) {
            endMeterPoint = queryMeterPointData.getMeterPoint();
            ScarMeasure = (endMeterPoint - startMeterPoint) * 1000;
            times++;
            System.out.println("endMeterPoint = " + endMeterPoint + "times = " + times);
        }
    }
    //选择一个距离当前位置最近的点并解析对应地址
    private Thread selectNearestPoint = new Thread() {
        @Override
        public void run() {
            double sCA = getDistance(sRoute.getAlatitude(), sRoute.getAlongitude());
            double sCB = getDistance(sRoute.getBlatitude(), sRoute.getBlongtitde());
            if(sCA <= sCB) {
                aOrb = "A";
                selectAddr = addressAnalysis(sRoute.getAlatitude(), sRoute.getAlongitude());
                end = addressAnalysis(sRoute.getBlatitude(), sRoute.getBlongtitde());
            } else {
                aOrb = "B";
                selectAddr = addressAnalysis(sRoute.getBlatitude(), sRoute.getBlongtitde());
                end = addressAnalysis(sRoute.getAlatitude(), sRoute.getAlongitude());
            }
            if(selectAddr.equals("") || end.equals("")) {
                selectAddr = "网络连接出错， 请检查网络连接！";
            } else {
                selectAddr = "请将车开到以下校准起点位置开始校准：\n" + selectAddr;
                end = "请将车开到以下校准终点位置完成校准：\n" + end;
            }
            handler.sendEmptyMessage(101);
        }
    };
    private Thread recordTrack = new Thread() {
        @Override
        public void run() {
            while(beginRecordTrack) {//隔一秒记录一次
                delay(1000);
                locationTracks.add(new LocationTrack(MyApp.locationMessageBody.getLongitude(), MyApp.locationMessageBody.getLatitude(),
                                                    MyApp.locationMessageBody.getSpeed(), TimeUtils.getStampTime()));
            }
            //记录完成后保存
        }
    };
    //检查是否到达指定起点附近
    private Thread checkIsReachStartPoint = new Thread() {
        @Override
        public void run() {
            double endLng;
            double endLat;
            double radius;
            if (aOrb.equals("A")) {
                endLng = sRoute.getAlongitude();
                endLat = sRoute.getAlatitude();
                radius = sRoute.getAradius();
            } else {
                endLat = sRoute.getBlatitude();
                endLng = sRoute.getBlongtitde();
                radius = sRoute.getBradius();
            }
            while(true) {
                if (getDistance(endLat, endLng) <= radius){
                    System.out.println("distance = " + getDistance(endLat, endLng));
                    //到达指定地点附近，获取里程点
                    TaxiMeterDataAnalysis.newInstance().getMeterPoint(TaxiMeterDataAnalysis.VERIFY_ADJUST);
                    beginVerify();
                    handler.sendEmptyMessage(102);
                    break;
                }
            }
        }
    };
    //开始校准
    private void beginVerify() {
        checkIsReachEndPoint.start();
        //保存校准起点的经纬度，速度，高度
        carMeasure.setAlongitude(getDouble4(MyApp.locationMessageBody.getLongitude()));
        carMeasure.setAlatitude(getDouble4(MyApp.locationMessageBody.getLatitude()));
        carMeasure.setAaltitude(getDouble4(MyApp.locationMessageBody.getAltitude()));
        carMeasure.setAspeed(getDouble4(MyApp.locationMessageBody.getSpeed()));
    }

    //检测是否到达校准终点附近
    private Thread checkIsReachEndPoint = new Thread() {
        @Override
        public void run() {
            double endLng;
            double endLat;
            double radius;
            if(aOrb.equals("B")) {
                endLng = sRoute.getAlongitude();
                endLat = sRoute.getAlatitude();
                radius = sRoute.getAradius();
            } else {
                endLat = sRoute.getBlatitude();
                endLng = sRoute.getBlongtitde();
                radius = sRoute.getBradius();
            }
            while(true) {
                if(getDistance(endLat, endLng) <= radius) {
                    TaxiMeterDataAnalysis.newInstance().getMeterPoint(TaxiMeterDataAnalysis.VERIFY_ADJUST);//查询计价器里程点，结果通过回调passQueryMeterData()方法，保存到 endMeterPoint中
                    handler.sendEmptyMessage(103);
                    break;
                }
            }
        }
    };

    //到达校准终点后处理数据
    private Thread finishVerify = new Thread() {
        @Override
        public void run() {
            carMeasure.setBlongtitde(getDouble4(MyApp.locationMessageBody.getLongitude()));
            carMeasure.setBlatitude(getDouble4(MyApp.locationMessageBody.getLatitude()));
            carMeasure.setBaltitude(getDouble4(MyApp.locationMessageBody.getAltitude()));
            carMeasure.setBspeed(getDouble4(MyApp.locationMessageBody.getSpeed()));
            //等待计价器返回里程点信息
            carMeasure.setScarMeasure(ScarMeasure);
            while(true) {
                if(ScarMeasure != 0){
                    carMeasure.setScarMeasure(ScarMeasure);
                    times = 0;//查询里程次数复位
                    break;
                }
            }
            double result = (ScarMeasure - sRoute.getStandard()) / sRoute.getStandard();
            if ((result >= -0.04) && (result <= 0.01)) {
                carMeasure.setIsRegular("yes");
            } else {
                carMeasure.setIsRegular("no");
            }
            boolean flag = true;
            int totalTime = 15;
            SharedPreferences.Editor editor = sp.edit();
            JSONObject pg = null;//= JsonUtils.mapToJsonObject(JsonUtils.toGson(new MessagePackaging(114).getReportSCarMeasureMap(carMeasure, locationTracks)));
            Log.d("MeterPoint", "开始上传:" + pg.toString());
            while (flag) {
                if (totalTime > 0) {//每隔一秒上传一次，共15次
                    if (httpJson.getPostJson() == null) {
                        httpJson.HttpJsonPost(pg, MyApp.serverUrl);
                    } else {//上传成功，收到回复后
                        try {
                            if (httpJson.getPostJson().getString("flag").equals("failure")) {//服务器出错
                                httpJson.setGetJson(null);
                            } else {//上传成功，停止循环，删除本地标准路线信息
                                flag = false;
                                editor.remove("StandardRouteNum");
                                editor.remove(Integer.toString(sRoute.getNum()));
                                editor.commit();
                                handler.sendEmptyMessage(104);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                    totalTime--;
                    delay(1000);
                } else {//上传15次后不成功，停止循环，保存校准数据到本地，删除标准路线
                    flag = false;
                    String cM = new Gson().toJson(carMeasure, CarMeasure.class);
                    editor.putString("CarMeasure", cM);
                    editor.remove("StandardRouteNum");
                    editor.remove(Integer.toString(sRoute.getNum()));
                    editor.commit();
                    handler.sendEmptyMessage(105);
                }
            }
        }
    };

    /**
     * 获取当前位置到指定地点的距离
     * @param endLat 指定纬度
     * @param endLng 指定经度
     * @return 两点间距离 单位：米
     */
    private double getDistance(double endLat, double endLng) {
        final double EARTH_RADIUS = 6378.137;//地球半径,单位千米
        double rightLng = MyApp.locationMessageBody.getLongitude();
        double rightLat = MyApp.locationMessageBody.getLatitude();
        double radLat1 = rad(rightLat);
        double radLat2 = rad(endLat);
        double a = radLat1 - radLat2;
        double b = rad(rightLng) - rad(endLng);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b/2),2)));
        s = s * EARTH_RADIUS;
        //s = Math.round(s * 10000) / 10000;
        return s * 1000;
    }
    private void alert(String s) {
        new AlertDialog.Builder(this).setTitle("提示！！！").setPositiveButton("确定", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
            }
         }).setMessage(s).create().show();
    }
    private void exitActivity(String s) {
        new AlertDialog.Builder(this).setTitle("提示：").setPositiveButton("确定", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                finish();
            }
        }).setMessage(s).create().show();
    }

    /**
     * {@code double} 类型保存四位小数
     * @param p
     * @return
     */
    private double getDouble4(double p) {
        return Double.parseDouble(format.format(p));
    }

    /**
     *  将度转化为弧度
     * @param d
     * @return
     */
    private double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     *  使用Android自带的Geocoder解析经纬度对应的地址
     * @param lat 纬度
     * @param lng 经度
     * @return
     */
    private String addressAnalysis(double lat, double lng) {
        String TAG = "PointTurn";
        Geocoder gc = new Geocoder(this, Locale.getDefault());
        List<Address> locationList;
        Address address;
        try {
            locationList = gc.getFromLocation(lat, lng, 1);
            if(locationList.size() != 0) {
                address = locationList.get(0);//得到Address实例
                Log.i(TAG, "address =" + address);
                return address.getAddressLine(0);//得到周边信息，包括街道等，i=0，得到街道名称
            } else {
                Log.d("VerifyAdjustActivity", "请检查网络连接！");
                //alert("网络连接出错， 请检查网络连接！");
                return null;
            }
        } catch (IOException e) {
            Log.d("VerifyAdjustActivity", "地址解析出错");
            //alert("地址解析出错");
            return null;
        }
    }
    private void waitProgress(String s){
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage(s);
        progressDialog.show();
        progressDialog.setCanceledOnTouchOutside(false);
    }

    /*/选择地址事件监听，暂时不用
    private RadioGroup.OnCheckedChangeListener checkedListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
            switch (checkedId) {
                case R.id.selectA:
                    selectAddr = textViewA.getText().toString();
                    end = textViewB.getText().toString();
                    aOrb = "A";
                    break;
                case R.id.selectB:
                    selectAddr = textViewB.getText().toString();
                    end = textViewA.getText().toString();
                    aOrb = "B";
                    break;
                default:
                    break;
            }
        }
    };
    //确定选择地址按钮事件监听，暂时不用
    private View.OnClickListener buttonListener = new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            if (selectAddr.equals("")){
                Toast.makeText(context, "请选择开始校准的起点", Toast.LENGTH_LONG).show();
            } else {
                runToBegin.setVisibility(View.INVISIBLE);
                textViewA.setVisibility(View.INVISIBLE);
                textViewB.setVisibility(View.INVISIBLE);
                selectA.setVisibility(View.INVISIBLE);
                selectB.setVisibility(View.VISIBLE);
                address.setVisibility(View.INVISIBLE);
                select.setVisibility(View.INVISIBLE);
                beginAddress.setVisibility(View.VISIBLE);
                beginAddress.setText("请前往该地点开始校准:\n"+selectAddr);
                openBaiduMap.setVisibility(View.VISIBLE);
                checkIsReachStartPoint.start();
            }
        }
    };

    /**
     *  延时
     * @param time 毫秒
     */
    private void delay(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        progressDialog.dismiss();
    }

}
